package bme.andraskindler.treenventory.provider;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;

import android.content.Context;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import bme.andraskindler.treenventory.TreenventoryApplication;
import bme.andraskindler.treenventory.activity.OptionsActivity;
import bme.andraskindler.treenventory.model.TreeData;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class RestManager {

	/**
	 * Generikus GET-függvény.
	 * @param url - a szerver címe
	 * @param clazz - a visszakapott objektum típusa
	 * @return
	 */
	private static <T> T getForObject(final String url, final Class<T> clazz) {

		final HttpClient httpclient = new DefaultHttpClient();
		final HttpGet httpget = new HttpGet(url);

		System.out.println(url);

		HttpResponse response;
		try {
			response = httpclient.execute(httpget);
			if (response.getStatusLine().getStatusCode() == 200) {
				final Gson gson = new Gson();
				final BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
				return gson.fromJson(reader, clazz);
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * Generikus POST-függvény.
	 * @param url - a szerver címe
	 * @param postobject - a POST-olandó objektum.
	 * @return - a kapcsolat státuszkódja
	 */
	private static int postForObject(final String url, final Object postobject) {
		final HttpClient httpclient = new DefaultHttpClient();
		final HttpPost httppost = new HttpPost(url);
		httppost.setHeader("Content-type", "application/json");
		final Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
		try {
			final StringEntity entity = new StringEntity(gson.toJson(postobject), HTTP.UTF_8);
			httppost.setEntity(entity);
			HttpResponse response = httpclient.execute(httppost);
			System.out.println(response.getStatusLine().getStatusCode());
			return response.getStatusLine().getStatusCode();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return 0;
	}

	/**
	 * A szerveren tárolt fák adatainak lekérése.
	 * 
	 * @return
	 */
	public static TreeData[] getTrees() {
		return getForObject(getBaseUrl(), TreeData[].class);
	}

	/**
	 * Fa POST-olása a szerverre.
	 * 
	 * @param treedata
	 * @return
	 */
	public static int postTree(final TreeData treedata) {
		return postForObject(getBaseUrl(), treedata);
	}

	/**
	 * Ezzel a függvénnyel lehet lekérdezni az internetkapcsolat típusát.
	 * 
	 * @param context
	 * @return
	 */
	public static NetInfo isNetworkAvailable(final Context context) {
		final ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

		boolean mobileNetworkAvailable = true;
		boolean wifiNetworkAvailable = true;

		final NetworkInfo[] infos = connectivityManager.getAllNetworkInfo();
		for (int i = 0; i < infos.length; i++) {
			final NetworkInfo info = infos[i];
			if (info.getType() == ConnectivityManager.TYPE_MOBILE && !info.isConnected()) {
				mobileNetworkAvailable = false;
			}
			if (info.getType() == ConnectivityManager.TYPE_WIFI && !info.isConnected()) {
				wifiNetworkAvailable = false;
			}
		}

		return new NetInfo(mobileNetworkAvailable, wifiNetworkAvailable);
	}

	/**
	 * Az internetkapcsolat adatait tartalmazza.
	 * 
	 * @author andraskindler
	 * 
	 */
	public static class NetInfo {
		public boolean mobile, wifi;

		public NetInfo(boolean m, boolean w) {
			mobile = m;
			wifi = w;
		}
	}

	/**
	 * Az IP-címmel kiegészített URL-lel tér vissza.
	 * 
	 * @return
	 */
	private static String getBaseUrl() {
		final SharedPreferences preferences = TreenventoryApplication.getInstance().getSharedPreferences(OptionsActivity.SETTINGS, Context.MODE_PRIVATE);
		final String ip = preferences.getString(OptionsActivity.SETTINGS_IP, "");
		System.out.println(ip);
		return "http://" + ip + ":8080/TreenventoryWeb/treeservice";
	}

}
